package example.ThreadTest;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PerformanceTestClient {
    private static Charset charset = Charset.forName("UTF-8");
    private static final int CLIENT_COUNT = 100;  // 并发客户端数量
    private static final int MESSAGES_PER_CLIENT = 100; // 每个客户端发送消息数
    
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(CLIENT_COUNT);
        CountDownLatch startLatch = new CountDownLatch(1);
        CountDownLatch endLatch = new CountDownLatch(CLIENT_COUNT);
        
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < CLIENT_COUNT; i++) {
            final int clientId = i;
            executor.execute(() -> {
                try {
                    startLatch.await(); // 等待开始信号
                    testClient(clientId);
                    endLatch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        
        System.out.println("开始性能测试...");
        startLatch.countDown(); // 同时启动所有客户端
        
        endLatch.await(); // 等待所有客户端完成
        long endTime = System.currentTimeMillis();
        
        executor.shutdown();
        
        long totalMessages = CLIENT_COUNT * MESSAGES_PER_CLIENT;
        long totalTime = endTime - startTime;
        double qps = totalMessages / (totalTime / 1000.0);
        
        System.out.println("性能测试结果:");
        System.out.println("总客户端数: " + CLIENT_COUNT);
        System.out.println("总消息数: " + totalMessages);
        System.out.println("总耗时: " + totalTime + "ms");
        System.out.println("QPS: " + String.format("%.2f", qps));
    }
    
    private static void testClient(int clientId) throws Exception {
        SocketChannel client = SocketChannel.open();
        client.connect(new InetSocketAddress("localhost", 8888));
        
        for (int i = 0; i < MESSAGES_PER_CLIENT; i++) {
            String message = "Client-" + clientId + "-Message-" + i;
            sendMessage(client, message);
            receiveResponse(client);
        }
        
        client.close();
    }
    
    private static void sendMessage(SocketChannel client, String message) throws Exception {
        byte[] messageData = message.getBytes(charset);
        ByteBuffer buffer = ByteBuffer.allocate(4 + messageData.length);
        
        buffer.putInt(messageData.length);
        buffer.put(messageData);
        buffer.flip();
        
        while (buffer.hasRemaining()) {
            client.write(buffer);
        }
    }
    
    private static void receiveResponse(SocketChannel client) throws Exception {
        ByteBuffer lengthBuffer = ByteBuffer.allocate(4);
        
        while (lengthBuffer.hasRemaining()) {
            client.read(lengthBuffer);
        }
        lengthBuffer.flip();
        int responseLength = lengthBuffer.getInt();
        
        ByteBuffer responseBuffer = ByteBuffer.allocate(responseLength);
        while (responseBuffer.hasRemaining()) {
            client.read(responseBuffer);
        }
        responseBuffer.flip();
        
        charset.decode(responseBuffer).toString(); // 忽略响应内容
    }
}